﻿using Microsoft.Extensions.DependencyInjection;
using System.Windows;
using Wpf.Ui;

namespace Koala.Pro.Services
{
    public class WindowsProviderService : IWindowsProviderService
    {
        private readonly IServiceProvider _serviceProvider;

        public WindowsProviderService(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public void Show<T>() where T : class
        {
            GetWindownInstance<T>().Show();
        }

        public void ShowDialog<T>() where T : class
        {
            GetWindownInstance<T>().ShowDialog();
        }

        public void Close<T>() where T : class
        {
            GetWindownInstance<T>().Close();
        }

        public void Hide<T>() where T : class
        {
            GetWindownInstance<T>().Hide();
        }

        public void Show(Type winType)
        {
            GetWindownInstance(winType).Show();
        }

        public void ShowDialog(Type winType)
        {
            GetWindownInstance(winType).ShowDialog();
        }

        public void Close(Type winType)
        {
            GetWindownInstance(winType).Close();
        }

        public void Hide(Type winType)
        {
            GetWindownInstance(winType).Hide();
        }

        private Window GetWindownInstance<T>()
        {
            if (!typeof(Window).IsAssignableFrom(typeof(T)))
            {
                throw new InvalidOperationException($"The window class should be derived from {typeof(Window)}.");
            }
            if (!(ServiceProviderServiceExtensions.GetService<T>(_serviceProvider) is Window window))
            {
                throw new InvalidOperationException("Window is not registered as service.");
            }
            if (window.Owner == null)
            {
                window.Owner = Application.Current.MainWindow;
            }
            return window;
        }

        private Window GetWindownInstance(Type winType)
        {
            if (!typeof(Window).IsAssignableFrom(winType))
            {
                throw new InvalidOperationException($"The window class should be derived from {typeof(Window)}.");
            }
            if (!(_serviceProvider.GetService(winType) is Window window))
            {
                throw new InvalidOperationException("Window is not registered as service.");
            }
            if (window.Owner == null)
            {
                window.Owner = Application.Current.MainWindow;
            }
            return window;
        }

        public virtual void Navigate(Type pageType)
        {
            App.ViewModel.CurrentPageOrWinType = pageType;
            if (typeof(Window).IsAssignableFrom(pageType))
            {
                ShowDialog(pageType);
            }
            else
            {
                ServiceProviderServiceExtensions.GetService<INavigationService>(_serviceProvider).Navigate(pageType);
            }
        }

        public void Navigate<T>() where T : class
        {
            Navigate(typeof(T));
        }
    }
}
